package com.minimalist.common.entity.basic.vo.tenant;

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.minimalist.common.config.swagger.SchemaEnum;
import com.minimalist.common.entity.basic.enums.StatusEnum;
import com.minimalist.common.entity.basic.enums.TenantEnum;
import com.minimalist.common.entity.basic.vo.storage.StorageVO;
import com.minimalist.common.entity.basic.vo.user.UserVO;
import com.minimalist.common.utils.Add;
import com.minimalist.common.utils.Update;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * @author 11987
 */
@Schema(name = "租户实体")
public class TenantVO implements Serializable{

    @Serial
    private static final long serialVersionUID = 1L;

    @JsonSerialize(using = ToStringSerializer.class)
    @NotNull(message = "租户ID不能为空", groups = {Update.class})
    @Schema(name = "tenantId", description = "租户ID", type = "string")
    private Long tenantId;

    @JsonSerialize(using = ToStringSerializer.class)
    @NotNull(message = "租户联系人不能为空", groups = {Update.class})
    @Schema(name = "userId", description = "用户ID，与租户绑定", type = "string")
    private Long userId;

    @Schema(name = "contactName", description = "联系人昵称，回显联系人使用", type = "string")
    private String contactName;

    @Schema(name = "email", description = "联系人邮箱，回显联系人使用", type = "string")
    private String email;

    @Schema(name = "phone", description = "联系人号码，回显联系人使用", type = "string")
    private String phone;

    @JsonSerialize(using = ToStringSerializer.class)
    @NotNull(message = "租户套餐ID不能为空", groups = {Add.class, Update.class})
    @Schema(name = "packageId", description = "租户套餐ID", type = "string")
    private Long packageId;

    @NotBlank(message = "租户名不能为空", groups = {Add.class, Update.class})
    @Schema(name = "tenantName", description = "租户名", type = "string")
    private String tenantName;

    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @NotNull(message = "租户过期时间不能为空", groups = {Add.class, Update.class})
    @Schema(name = "expireTime", description = "租户过期时间", type = "string")
    private LocalDateTime expireTime;

    @NotNull(message = "可创建账号数量不能为空", groups = {Add.class, Update.class})
    @Schema(name = "accountCount", description = "可创建账号数量，表示这个租户下可以创建多少账号", type = "integer")
    private Integer accountCount;

    @NotBlank(message = "数据隔离方式不能为空", groups = {Add.class, Update.class})
    @SchemaEnum(implementation = TenantEnum.DataIsolation.class)
    @Schema(name = "dataIsolation", description = "数据隔离方式", type = "string")
    private String dataIsolation;

    @Schema(name = "datasource", description = "所使用的数据源，默认使用master主库", type = "string")
    private String datasource;

    @JsonSerialize(using = ToStringSerializer.class)
    @NotNull(message = "存储ID不能为空", groups = {Add.class, Update.class})
    @Schema(name = "storageId", description = "存储ID 表示该租户使用哪个文件存储", type = "string")
    private Long storageId;

    @NotNull(message = "租户状态不能为空", groups = {Update.class})
    @SchemaEnum(implementation = StatusEnum.class)
    @Schema(name = "status", description = "租户状态", type = "integer")
    private Byte status;

    @Schema(name = "remark", description = "备注", type = "string")
    private String remark;

    @NotNull(message = "租户的用户信息不能为空", groups = {Add.class})
    @Schema(name = "user", description = "租户的用户信息，新增时填充", type = "object")
    private UserVO user;

    @NotNull(message = "租户数据源不能为空", groups = {Add.class})
    @Schema(name = "tenantDatasource", description = "租户数据源", type = "object")
    private TenantDatasourceVO tenantDatasource;

    @Schema(name = "tenantDatasource", description = "租户文件存储", type = "object")
    private StorageVO storage;

    public Long getTenantId() {
        return tenantId;
    }

    public void setTenantId(Long tenantId) {
        this.tenantId = tenantId;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getContactName() {
        return contactName;
    }

    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Long getPackageId() {
        return packageId;
    }

    public void setPackageId(Long packageId) {
        this.packageId = packageId;
    }

    public String getTenantName() {
        return tenantName;
    }

    public void setTenantName(String tenantName) {
        this.tenantName = tenantName;
    }

    public LocalDateTime getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(LocalDateTime expireTime) {
        this.expireTime = expireTime;
    }

    public Integer getAccountCount() {
        return accountCount;
    }

    public void setAccountCount(Integer accountCount) {
        this.accountCount = accountCount;
    }

    public String getDataIsolation() {
        return dataIsolation;
    }

    public void setDataIsolation(String dataIsolation) {
        this.dataIsolation = dataIsolation;
    }

    public String getDatasource() {
        return datasource;
    }

    public void setDatasource(String datasource) {
        this.datasource = datasource;
    }

    public Long getStorageId() {
        return storageId;
    }

    public void setStorageId(Long storageId) {
        this.storageId = storageId;
    }

    public Byte getStatus() {
        return status;
    }

    public void setStatus(Byte status) {
        this.status = status;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public UserVO getUser() {
        return user;
    }

    public void setUser(UserVO user) {
        this.user = user;
    }

    public TenantDatasourceVO getTenantDatasource() {
        return tenantDatasource;
    }

    public void setTenantDatasource(TenantDatasourceVO tenantDatasource) {
        this.tenantDatasource = tenantDatasource;
    }

    public StorageVO getStorage() {
        return storage;
    }

    public void setStorage(StorageVO storage) {
        this.storage = storage;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TenantVO tenantVO = (TenantVO) o;
        return java.util.Objects.equals(tenantId, tenantVO.tenantId) &&
               java.util.Objects.equals(userId, tenantVO.userId) &&
               java.util.Objects.equals(contactName, tenantVO.contactName) &&
               java.util.Objects.equals(email, tenantVO.email) &&
               java.util.Objects.equals(phone, tenantVO.phone) &&
               java.util.Objects.equals(packageId, tenantVO.packageId) &&
               java.util.Objects.equals(tenantName, tenantVO.tenantName) &&
               java.util.Objects.equals(expireTime, tenantVO.expireTime) &&
               java.util.Objects.equals(accountCount, tenantVO.accountCount) &&
               java.util.Objects.equals(dataIsolation, tenantVO.dataIsolation) &&
               java.util.Objects.equals(datasource, tenantVO.datasource) &&
               java.util.Objects.equals(storageId, tenantVO.storageId) &&
               java.util.Objects.equals(status, tenantVO.status) &&
               java.util.Objects.equals(remark, tenantVO.remark) &&
               java.util.Objects.equals(user, tenantVO.user) &&
               java.util.Objects.equals(tenantDatasource, tenantVO.tenantDatasource) &&
               java.util.Objects.equals(storage, tenantVO.storage);
    }

    @Override
    public int hashCode() {
        return java.util.Objects.hash(tenantId, userId, contactName, email, phone, packageId, tenantName, expireTime, accountCount, dataIsolation, datasource, storageId, status, remark, user, tenantDatasource, storage);
    }

    @Override
    public String toString() {
        return "TenantVO{" +
               "tenantId=" + tenantId +
               ", userId=" + userId +
               ", contactName='" + contactName + '\'' +
               ", email='" + email + '\'' +
               ", phone='" + phone + '\'' +
               ", packageId=" + packageId +
               ", tenantName='" + tenantName + '\'' +
               ", expireTime=" + expireTime +
               ", accountCount=" + accountCount +
               ", dataIsolation='" + dataIsolation + '\'' +
               ", datasource='" + datasource + '\'' +
               ", storageId=" + storageId +
               ", status=" + status +
               ", remark='" + remark + '\'' +
               ", user=" + user +
               ", tenantDatasource=" + tenantDatasource +
               ", storage=" + storage +
               '}';
    }

}
